Skip to content

fix(config): avoid exporting persistent allow-scripts - #9913

Open
Fnine59 wants to merge 4 commits into
npm:latestfrom
Fnine59:fix/npm-allow-scripts-env-9912
Open

fix(config): avoid exporting persistent allow-scripts#9913
Fnine59 wants to merge 4 commits into
npm:latestfrom
Fnine59:fix/npm-allow-scripts-env-9912

Conversation

@Fnine59

@Fnine59 Fnine59 commented Aug 24, 2026

Copy link
Copy Markdown

What / Why

A user or global .npmrc can define allow-scripts as persistent policy. setEnvs() currently carries that non-default value into lifecycle child processes as npm_config_allow_scripts. If a lifecycle script runs a nested project-scoped npm install, the inner process treats the inherited value as an environment override and rejects it with EALLOWSCRIPTS instead of reloading the policy from its persistent config source.

Mark allow-scripts as non-exportable. This only prevents setEnvs() from synthesizing the lifecycle environment variable; it does not remove an explicitly supplied environment value or change how the outer command reads its config. Pacote's git-preparation environment filtering and #9783 are outside this change.

The regression test models a user-level value in the inherited config chain and verifies that lifecycle scripts do not receive npm_config_allow_scripts.

AI assistance

OpenAI Codex assisted with analysis, implementation, and test design. The patch was verified with the focused regression, the complete @npmcli/config suite, lint, and template checks.

References

Fixes #9912

undefined,
'persistent policy is reloaded instead of exported to lifecycle scripts'
)
t.end()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please extend this test so we can test that an already-present explicit npm_config_allow_scripts value must remain unchanged. We only want to stop npm from synthesizing the variable from persistent config; explicitly injected environment policy must remain visible so resolveAllowScripts()  can reject it during project installs.

Something like this:

  envConf['allow-scripts'] = 'sharp'
  env.npm_config_allow_scripts = 'sharp'
  setEnvs(config)
  t.equal(
    env.npm_config_allow_scripts,
    'sharp',
    'an explicit environment policy remains inherited'
  )
  t.end()

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in 3a3a553: the setEnvs coverage now preloads an explicit npm_config_allow_scripts=sharp value and verifies that it remains unchanged. Verified with Node 24.15.0; the full @npmcli/config test suite passes with 100% coverage, and ESLint passes for the changed files.

@@ -241,3 +241,31 @@ t.test('dont set configs marked as envExport:false', t => {
t.strictSame(env, { ...extras }, 'not exported, because envExport=false')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, help us adding this test in resolve-allow-scripts.js so we have good test coverage for this fix

t.test('allow-scripts environment policy is rejected in project-scoped installs', async t => {
  const mock = await mockNpm(t, {
    prefixDir: {
      'package.json': JSON.stringify({ name: 'p' }),
    },
    globals: {
      'process.env.npm_config_allow_scripts': 'canvas',
    },
  })
  const resolveAllowScripts = loadResolver(t)
  await t.rejects(
    resolveAllowScripts(mock.npm),
    { code: 'EALLOWSCRIPTS', message: /--allow-scripts is not allowed/ }
  )
})

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in 3a3a553: resolve-allow-scripts now covers a project-scoped install with npm_config_allow_scripts=canvas and asserts EALLOWSCRIPTS. The targeted resolver test and ESLint pass with Node 24.15.0.

default: '',
type: [String, Array],
hint: '<package-list>',
envExport: false,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix. Marking allow-scripts  as envExport: false is the right shared solution: it prevents Config.load() / setEnvs() from turning file-backed policy into an environment-layer override before either npm run or Pacote Git preparation starts a child process. This addresses #9912 and actually fixes the persistent- .npmrc case in #9783 .

@martinrrm martinrrm self-assigned this Aug 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] A user/local .npmrc allow-scripts setting is forwarded to an inner npm install spawned by npm run-script and fails with EALLOWSCRIPTS

2 participants